{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# 基于PaddleX的人脸、戴口罩和吸烟目标检测"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## 一、安装PaddleX"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!pip install paddlex==2.0.0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## 二、解压数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!unzip -oq /home/aistudio/data/data128757/VOC_MASK_smoke.zip "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## 三、生成数据集文件\n",
    "\n",
    "PaddleX支持VOC格式数据，\n",
    "## **安装Paddlex**\n",
    "\t首先安装1.83以上版本的Paddlex（1.83一下版本的已经不支持此划分命令）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "#如果下一句代码报错，请先运行此代码\r\n",
    "#!pip install paddlex==2.0rc -q"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!paddlex --split_dataset --format VOC --dataset_dir VOC_MASK_smoke --val_value 0.2 --test_value 0.1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## 四、数据预处理\n",
    "这里使用了图像混合、随机像素变换、随机膨胀、随即裁剪、随机水平翻转等数据增强方法。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from paddlex import transforms as T\r\n",
    "\r\n",
    "train_transforms = T.Compose([\r\n",
    "    T.MixupImage(mixup_epoch=250), T.RandomDistort(),\r\n",
    "    T.RandomExpand(im_padding_value=[123.675, 116.28, 103.53]), T.RandomCrop(),\r\n",
    "    T.RandomHorizontalFlip(), T.BatchRandomResize(\r\n",
    "        target_sizes=[320, 352, 384, 416, 448, 480, 512, 544, 576, 608],\r\n",
    "        interp='RANDOM'), T.Normalize(\r\n",
    "            mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\r\n",
    "])\r\n",
    "\r\n",
    "eval_transforms = T.Compose([\r\n",
    "    T.Resize(\r\n",
    "        608, interp='CUBIC'), T.Normalize(\r\n",
    "            mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\r\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "\r\n",
    "train_dataset = pdx.datasets.VOCDetection(\r\n",
    "    data_dir='VOC_MASK_smoke',\r\n",
    "    file_list='VOC_MASK_smoke/train_list.txt',\r\n",
    "    label_list='VOC_MASK_smoke/labels.txt',\r\n",
    "    transforms=train_transforms,\r\n",
    "    shuffle=True)\r\n",
    "eval_dataset = pdx.datasets.VOCDetection(\r\n",
    "    data_dir='VOC_MASK_smoke',\r\n",
    "    file_list='VOC_MASK_smoke/val_list.txt',\r\n",
    "    label_list='VOC_MASK_smoke/labels.txt',\r\n",
    "    transforms=eval_transforms)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## 五、训练模型\n",
    "这里定义了一个YOLOv3，使用DarkNet53作为主干网络（该参数训练50epoch差不多就收敛了）；"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import paddlex as pdx\r\n",
    "num_classes = len(train_dataset.labels)\r\n",
    "model = pdx.det.YOLOv3(num_classes=num_classes, backbone='DarkNet53')\r\n",
    "model.train(\r\n",
    "    num_epochs=270,\r\n",
    "    train_dataset=train_dataset,\r\n",
    "    train_batch_size=8,\r\n",
    "    eval_dataset=eval_dataset,\r\n",
    "    learning_rate=0.000125,\r\n",
    "    lr_decay_epochs=[216, 243],\r\n",
    "    warmup_steps=1000,\r\n",
    "    warmup_start_lr=0.0,\r\n",
    "    save_interval_epochs=5,\r\n",
    "    save_dir='output/yolov3_darknet53',\r\n",
    "    use_vdl=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## 六、模型检测结果及可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import paddlex as pdx\r\n",
    "eval_details_file = 'output/yolov3_darknet53/best_model/eval_details.json'\r\n",
    "pdx.det.draw_pr_curve(eval_details_file, save_dir='./output/yolov3_darknet53')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# 目标检测/实例分割准确率-召回率可视化\n",
    "\n",
    "![](https://ai-studio-static-online.cdn.bcebos.com/50e7d2e4958c4cb4b83f1dc9e1e41058bb4ec03a872c4598b81d7357a886ace0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2022-02-20 15:29:23 [INFO]\tModel[YOLOv3] loaded.\n",
      "2022-02-20 15:29:23 [INFO]\tThe visualized result is saved at ./output/yolov3_darknet53/visualize_1_Handshaking_Handshaking_1_164.jpg\n"
     ]
    }
   ],
   "source": [
    "#预测模型\r\n",
    "import paddlex as pdx\r\n",
    "model = pdx.load_model('output/yolov3_darknet53/best_model')\r\n",
    "image_name = 'VOC_MASK_smoke/JPEGImages/1_Handshaking_Handshaking_1_164.jpg'\r\n",
    "result = model.predict(image_name)\r\n",
    "pdx.det.visualize(image_name, result, threshold=0.5, save_dir='./output/yolov3_darknet53')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "\n",
    "![](https://ai-studio-static-online.cdn.bcebos.com/9dfd2df10171457ca16e96ccbb5618968fc4643ac55140fe89e75586cedbf646)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "py35-paddle1.2.0"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
